---
slug: /troubleshooting
---

# Troubleshooting

This page describes problems you may encounter when using Dagger, and their solutions.

## Dagger is unresponsive with a BuildKit error

A Dagger Function may hang or become unresponsive, eventually generating a BuildKit error such as `buildkit failed to respond` or `container state improper`.

To resolve this error, you must stop and remove the Dagger Engine container and (optionally) clear the container state.

1. Stop and remove the Dagger Engine container:

   ```shell
   DAGGER_ENGINE_DOCKER_CONTAINER="$(docker container list --all --filter 'name=^dagger-engine-*' --format '{{.Names}}')"
   docker container stop "$DAGGER_ENGINE_DOCKER_CONTAINER"
   docker container rm "$DAGGER_ENGINE_DOCKER_CONTAINER"
   ```

1. Clear unused volumes and data:

   :::info
   This step is optional. It will remove the cache and result in a slow first run when the container is re-provisioned.
   :::

   ```shell
   docker volume prune
   docker system prune
   ```

You should now be able to run your Dagger Function successfully.

:::note
If you have custom-provisioned the Dagger Engine, please adjust the above commands to your environment.
:::

## Dagger is unable to resolve host names after network configuration changes

If the network configuration of the host changes after the Dagger Engine container starts, Docker does not notify the Dagger Engine of the change. This may cause Dagger to fail with network-related errors.

As an example, if the nameserver configuration of the host changes after switching to a different network connection or connecting/disconnecting a VPN result, Dagger may fail with DNS resolution errors.

To resolve this error, you must restart the Dagger Engine container after the host network configuration changes.

```shell
DAGGER_ENGINE_DOCKER_CONTAINER="$(docker container list --all --filter 'name=^dagger-engine-*' --format '{{.Names}}')"
docker restart "$DAGGER_ENGINE_DOCKER_CONTAINER"
```

You should now be able to re-run your Dagger Function successfully.

## Dagger restarts with a "CNI setup error"

The Dagger Engine requires the `iptable_nat` Linux kernel module in order to function properly. On some Linux distributions this module is not loaded by default.

Known affected platforms include Red Hat Enterprise Linux (8.x and 9.x) and Podman Desktop on Mac.

You can load this module by running `sudo modprobe iptable_nat`.

To have this module loaded automatically on startup, add it to the `/etc/modules-load.d/modules` file with the following command:

```shell
echo iptable_nat | sudo tee -a /etc/modules-load.d/modules
```

## Calling a Dagger Function fails with an error

### Errors related to code generation

A Dagger Function may fail with one of the following errors and/or cause the Dagger Engine to crash:

- `unable to start container process`
- `failed to update codegen and runtime`
- `failed to generate code`
- `failed to get modified source directory for go module sdk codegen`

This can occur when you have the `DOCKER_DEFAULT_PLATFORM` environment variable set and/or when Rosetta is enabled in Docker Desktop for Mac.

To resolve this error, you must remove the environment variable, disable Rosetta if applicable, and remove existing Dagger Engine containers.

1. Remove the `DOCKER_DEFAULT_PLATFORM` variable in your current shell and/or your equivalent shell config files (`.bashrc`, `.profile`, `.zshrc`, ...) and restart the shell.
1. Ensure that [Rosetta is disabled in Docker Desktop on Mac](https://docs.docker.com/desktop/settings/mac/).
1. Remove any running Dagger Engine containers and Docker images:

    ```shell
    docker rm -fv $(docker ps --filter name="dagger-engine-*" -q) && docker rmi $(docker images -q --filter reference=registry.dagger.io/engine)
    ```

### An agent isn't behaving properly

First, to get more information about the agent's behavior, increase the verbosity of the shell or review the trace in Dagger Cloud. This is the best way to see what steps the LLM took, the details of its thinking between each tool call, and what the tool calls were.

Second, once you understand how the agent is behaving, you can try to adjust the prompt to get the desired behavior. This is often a matter of trial and error, and can be a bit of an art.

### Other errors

To troubleshoot other Dagger Function errors, try the following techniques.

#### Rerun commands with `--interactive`

Run `dagger call` with the `--interactive` (`-i` for short) flag to open a terminal in the context of a workflow failure. No changes are required to your Dagger Function code.

:::tip
Interactive mode defaults to executing `/bin/sh` when opening a terminal. Change the command to execute with the `--interactive-command` flag.
:::

#### Rerun commands with `--debug`

The Dagger CLI tries to keep its output concise by default. If you're running
into issues and want to debug with more detailed output, you can run any `dagger`
subcommand with the `--debug` flag to have it reveal all available information.

#### Access the Dagger Engine logs

The Dagger Engine runs in a dedicated Docker container and emits log messages as it works. Here's how to access these logs:

```shell
DAGGER_ENGINE_DOCKER_CONTAINER="$(docker container list --all --filter 'name=^dagger-engine-*' --format '{{.Names}}')"
docker logs $DAGGER_ENGINE_DOCKER_CONTAINER
```

#### Enable SDK debug logs

:::important
The information in this section is only applicable to the Python SDK. Debug logs are not currently available for the Go and TypeScript SDKs.
:::

The Python SDK prints debugging information at various steps of the execution
flow of a module, which can be very useful in understanding what's being
received from and sent to the API.

This is done using standard Python [logging](https://docs.python.org/3/howto/logging.html),
so it's highly configurable (for example, saving to a file or sending to an
external system like Sentry). But for a simple lowering of the default logging
level to [logging.DEBUG](https://docs.python.org/3/library/logging.html#logging.DEBUG),
there's a convenience function for that:

```python
import logging

from dagger import function, object_type
from dagger.log import configure_logging

configure_logging(logging.DEBUG)


@object_type
class MyModule:
    @function
    def echo(self, msg: str) -> str:
        return msg
```

:::important
With the TUI, you need to use a progress output that doesn't collapse on success
like `--progress=plain` or `--debug`, otherwise it won't show in the terminal.
:::

Using the command `dagger call --debug echo --msg="hello"`, you should see a large number of debug messages, eventually ending with output similar to the below:

```
  ✔ connect 0.1s
✔ Debug.echo(msg: "hello"): String! 0.9s
┃ [DEBUG] dagger.mod._resolver: func => <Signature (msg: str) -> str>
┃ [DEBUG] dagger.mod._resolver: input args => {'msg': 'hello'}
┃ [DEBUG] dagger.mod._resolver: structured args => {'msg': 'hello'}
┃ [DEBUG] dagger.mod._module: result => 'hello'
┃ [DEBUG] dagger.mod._module: output => '"hello"'
┃ [DEBUG] dagger.client._session: Closing client session to GraphQL server

hello
```

The above gives a lot of useful information:
- The function and parent object that the API wants to execute
- The parent object's state
- The function's signature
- The user inputs before and after deserialization
- The user inputs after being converted to more complex types (structuring)
- The function's result before and after serialization
